package com.clp.protocol.iec104.iec104.server.slavechannel.pipeline.state.control;

import com.clp.protocol.iec104.iec104.apdu.Apdu;
import com.clp.protocol.iec104.iec104.apdu.IApdu;
import com.clp.protocol.iec104.iec104.apdu.SApdu;
import com.clp.protocol.iec104.iec104.apdu.UApdu;
import com.clp.protocol.iec104.iec104.server.slavechannel.pipeline.PipelineManager;
import com.clp.protocol.iec104.iec104.server.slavechannel.pipeline.state.AbstractStateHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;

public abstract class AbstractControlStateHandler extends AbstractStateHandler {
    protected AbstractControlStateHandler(PipelineManager manager) {
        super(manager);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg == null) return;
        if (!(msg instanceof Apdu)) {
            ctx.fireChannelRead(msg);
            return;
        }

        Apdu apdu = null;
        try {
            if (msg instanceof UApdu) {
                apdu = updateStateByRecv(((UApdu) msg));
            } else if (msg instanceof SApdu) {
                apdu = updateStateByRecv(((SApdu) msg));
            } else if (msg instanceof IApdu) {
                apdu = updateStateByRecv(((IApdu) msg));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
        if (apdu == null) return;
        ctx.fireChannelRead(apdu);
    }

    protected abstract UApdu updateStateByRecv(UApdu uApdu) throws Exception;

    protected abstract SApdu updateStateByRecv(SApdu sApdu) throws Exception;

    protected abstract IApdu updateStateByRecv(IApdu iApdu) throws Exception;

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        if (msg == null) return;
        if (!(msg instanceof Apdu)) {
            ctx.write(msg, promise);
            return;
        }

        Apdu apdu = null;
        try {
            if (msg instanceof UApdu) {
                apdu = updateStateBySend(((UApdu) msg));
            } else if (msg instanceof SApdu) {
                apdu = updateStateBySend(((SApdu) msg));
            } else if (msg instanceof IApdu) {
                apdu = updateStateBySend(((IApdu) msg));
            }
        } catch (Exception e) {
            promise.setFailure(e);
            return;
        }
        if (apdu == null) {
            promise.setFailure(new IllegalStateException("发送的apdu更新状态时被过滤"));
            return;
        }
        ctx.write(msg, promise);
    }

    protected abstract UApdu updateStateBySend(UApdu uApdu) throws Exception;

    protected abstract SApdu updateStateBySend(SApdu sApdu) throws Exception;

    protected abstract IApdu updateStateBySend(IApdu iApdu) throws Exception;
}
